<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <style>
      .line {
        margin-top: 2px;
        display: flex;
      }

      b {
        flex-shrink: 0;
        width: 40px;
        font-size: 14px;
        color: gray;
      }

      .char {
        margin-left: 2px;
        flex-shrink: 0;
        width: 20px;
        height: 20px;
        font-size: 16px;
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <select id="select">
      <option>0</option>
      <option>1</option>
      <option>2</option>
    </select>
    <select id="font">
      <option>serif</option>
      <option>sans-serif</option>
      <option>monospace</option>
    </select>
    <select id="width">
      <option>16</option>
      <option>32</option>
      <option>64</option>
    </select>
    <div id="container"></div>
    <script>
      const PAGE_SIZE = 0x10000;

      const select = document.getElementById('select')
      const sfont = document.getElementById('font')
      const swidth = document.getElementById('width')
      const container = document.getElementById('container')

      function show() {
        container.innerHTML = ''
        const page = Number(select.options[select.selectedIndex].value)
        const width = Number(swidth.options[swidth.selectedIndex].value)
        const height = PAGE_SIZE / width;
        for (let i = 0; i < height; i++) {
          const line = document.createElement('div')
          line.className = 'line'
          const b = document.createElement('b')
          b.innerText = (i * width + 0x10000).toString(16).substring(1)
          line.appendChild(b)
          for (let j = 0; j < width; j++) {
            const char = document.createElement('div')
            char.className = 'char'
            char.innerText = String.fromCodePoint(page * PAGE_SIZE + i * width + j)
            line.appendChild(char)
          }
          container.appendChild(line)
        }
      }
      show()
      select.onchange = show
      swidth.onchange = show

      function changeFont() {
        container.style.fontFamily = sfont.options[sfont.selectedIndex].value
      }
      changeFont()
      sfont.onchange = changeFont
    </script>
  </body>
</html>
